package com.uco.reflect;

import org.junit.jupiter.api.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;

public class ReflectDemo {
    @Test
    public void testConstructor() throws Exception {
        Class d = Dog.class;
        Constructor[] declaredConstructors = d.getDeclaredConstructors();
        for (Constructor constructor : declaredConstructors) {
            System.out.println("name: "+ constructor.getName() + " - parameterTypes: " + Arrays.toString(constructor.getParameterTypes()));
        }
        // 获取构造器对象，并利用进行实例化
        Constructor constructor = d.getConstructor(String.class, int.class);
        Dog d1 = (Dog) constructor.newInstance("Dog", 1);
        d1.show();

        Constructor privageConstructor = d.getDeclaredConstructor();
        // 获取私有构造器对象，改变其访问权限
        privageConstructor.setAccessible(true);
        Dog d2 = (Dog) privageConstructor.newInstance();
        d2.show();
    }

    @Test
    public void testFields() throws Exception {
        Dog d = new Dog("Dog", 1);
        Class dClass = d.getClass();
        Field[] declaredFields = dClass.getDeclaredFields();
        for (Field field : declaredFields) {
            System.out.println("name: "+ field.getName() + " - type: " + field.getType());
        }
        Field fname = dClass.getDeclaredField("name");
        fname.setAccessible(true);
        // 修改实例属性值
        fname.set(d, "Dog2");
    }

    @Test
    public void testMethods() throws Exception {
        Class d = Class.forName("com.uco.reflect.Dog");
        Method[] declaredMethods = d.getDeclaredMethods();
        for (Method method : declaredMethods) {
            System.out.println("name: "+ method.getName() + " - parameterTypes: " + Arrays.toString(method.getParameterTypes()));
        }
        Method show = d.getDeclaredMethod("show");
        // 调用实例方法
        show.invoke(d.getConstructor(String.class, int.class).newInstance("金毛", 1));
    }
}
